use yew::prelude::*;
use yew::{Component, ComponentLink, Html};
use std::ops::Range;

#[derive(Properties, Clone, PartialEq, Debug)]
pub struct Props {
    pub total: u64,
    pub pages: u64,
    pub pageNo: u64,
    pub pageSize: u64,
    pub click: Callback<u64>
}

pub enum Action { Click(u64) }

pub struct Pagination {
    props: Props,
    link: ComponentLink<Self>
}

impl Pagination {
    fn get_display_pages(&self) -> Range<u64> {
        let no = self.props.pageNo as i32;
        let ps = self.props.pages as i32;

        let (start, end) = if ps < 5 { (1, ps) } else {
            let mut x = no - 2;
            let mut y = no + 2;
            if x < 1 {
                x = 1;
                y = x + 4;
            }
            if y > ps {
                y = ps;
                x = y - 4;
            }
            (x, y)
        };

        (start as u64..(end + 1) as u64)
    }
}

impl Component for Pagination {
    type Message = Action;
    type Properties = Props;

    fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
        Self { props, link }
    }

    fn update(&mut self, msg: Self::Message) -> bool {
        match msg {
            Action::Click(i) => {
                self.props.pageNo = i;
                self.props.click.emit(i);
            }
        }
        true
    }

    fn change(&mut self, props: Self::Properties) -> bool {
        if self.props != props {
            self.props = props;
            true
        } else {
            false
        }
    }

    fn view(&self) -> Html {
        let ps = self.props.pages;
        let start = if self.props.pageNo == 1 {
            html! { <li class="page-item disabled"><a class="page-link" href="#">{"«"}</a></li> }
        } else {
            html! { <li class="page-item">
                <a onclick=self.link.callback(|_| Action::Click(1))
                class="page-link" href="#">{"«"}</a></li> }
        };
        let end = if self.props.pages == self.props.pageNo {
            html! { <li class="page-item disabled"><a class="page-link" href="#">{"»"}</a></li> }
        } else {
            html! { <li class="page-item">
                <a onclick=self.link.callback(move |_| Action::Click(ps))
                class="page-link" href="#">{"»"}</a></li> }
        };
        let ps = self.get_display_pages().map(|x| {
            let active = if x == self.props.pageNo { "page-item active" } else {"page-item"};
            html! { <li class={active}>
                <a onclick=self.link.callback(move |_| Action::Click(x))
                class="page-link" href="#">{x}</a></li> }
        });

        html! {
            <div class="d-flex justify-content-end">
                <ul class="pagination">
                    { start }
                    { for ps }
                    { end }
                </ul>
            </div>
        }
    }
}